/**
 * 地图核心功能 Composable
 * 统一管理 GodViewer 和相关的地图核心功能
 */
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { ShowFrustum, Tools, WayLine, CameraFrustum, ViewDegree } from '../assets/cesiumFunction/SmartView'
import { areaLayerName } from "../assets/cesiumFunction/LayerName"
import { v4 as uuidv4 } from 'uuid'
import * as Cesium from 'cesium'

// 导入 GlobeTracker
// import '../../public/lib/cesium/GlobeTracker.js'

// 单例模式，确保全局只有一个实例
let mapCoreInstance = null

export function useMapCore() {
  // 如果已经存在实例，直接返回
  if (mapCoreInstance) {
    return mapCoreInstance
  }

  const route = useRoute()
  
  // 核心地图相关响应式数据
  const MapProvider2D = ref(null)
  const MapProvider3D = ref(null)
  const GodViewer = ref(null)
  const UavViewer = ref(null)
  const tracker = ref(null)
  
  // 其他地图相关数据
  const uav_height = ref(80)
  const target_height = ref(30)
  const frustumVisible = ref(true)
  const showFrustum = ref(null)
  const drawWayLine = ref(null)
  const hightLight = ref(null)
  
  // 其他数据
  const pointRecord = ref([])
  const areaRecord = ref([])

  /**
   * 初始化地图
   */
  const initMap = async (routeData) => {
    GodViewer.value = Tools.BuildViewer("GodMapPanel")
    tracker.value = new GlobeTracker(GodViewer.value)
    await handleMapMode(routeData)
  }

  /**
   * 根据模式处理地图初始化
   */
  const handleMapMode = async (routeData) => {
    switch (Number(route.query.mode)) {
      case 0:
        await initPointMode(routeData)
        break
      case 1:
        await initAreaMode(routeData)
        break
      case 2:
        await init3DAreaMode(routeData)
        break
      case 3:
        await initLineMode(routeData)
        break
      case 4:
        await initBuildingMode(routeData)
        break
      default:
        console.log("默认其他，待完善")
        break
    }
  }

  /**
   * 初始化逐点模式
   */
  const initPointMode = async (routeData) => {
    // 先处理航点数据
    processPointRecord(routeData)
    
    // 设置相机视角
    if (pointRecord.value.length > 0) {
      const firstPoint = pointRecord.value[0]
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(
          firstPoint.camera_lng,
          firstPoint.camera_lat,
          10000.0
        ),
      })
    } else {
      // 如果没有航点数据，使用config.js中的initialPosition
      const initialPos = window.SystemConfig?.initialPosition?.destination
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(...initialPos),
      })
    }
    
    // 初始化 UAV 查看器（仅在模式 0 时）
    if (route.query.mode === '0') {
      UavViewer.value = Tools.BuildViewer("UavMapPanel")
    }
    
    // 绘制航线
    if (pointRecord.value.length > 0) {
      drawWayLine.value = new WayLine(GodViewer.value, "line", "relative", 0)
      drawWayLine.value.BuildEntities(
        pointRecord.value,
        "camera_lng",
        "camera_lat",
        "camera_ground_height",
        "target_lng",
        "target_lat",
        "target_ground_height",
        "sky_index",
        "target_index",
        "fieldOfView",
        "aspect"
      )
      
      // 初始化视锥显示（仅在模式 0 时）
      if (route.query.mode === '0') {
        showFrustum.value = new ShowFrustum(GodViewer.value, "/Model/UAV.glb", 90)
      }
    }
  }

  /**
   * 初始化平面区域模式
   */
  const initAreaMode = async (routeData) => {
    processAreaRecord(routeData)
    
    // 检查是否有polygon数据
    if (routeData.wayline_folder.polygon && routeData.wayline_folder.polygon.length > 0) {
      const LonLat = []
      const objId = uuidv4()
      routeData.wayline_folder.polygon.map((item) => {
        LonLat.push(Number(item.longitude))
        LonLat.push(Number(item.latitude))
      })
      const positions = Cesium.Cartesian3.fromDegreesArray(LonLat)
      areaRecord.value = positions
      await showArea(objId, positions, areaLayerName)
      
      // 设置相机视角到区域的第一个点
      const pointLoc = routeData.wayline_folder.polygon[0]
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(Number(pointLoc.longitude), Number(pointLoc.latitude), 1200.0),
      })
    } else {
      // 如果没有区域数据，使用config.js中的initialPosition
      const initialPos = window.SystemConfig?.initialPosition?.destination
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(...initialPos),
        orientation: {
          heading: 6.283185307179586,
          pitch: -1.5686521559334161,
          roll: 0,
        }
      })
    }
  }

  /**
   * 初始化3D区域模式
   */
  const init3DAreaMode = async (routeData) => {
    const LonLat = []
    const objId = uuidv4()
    
    if (routeData.wayline_folder.polygon && routeData.wayline_folder.polygon.length > 0) {
      process3DAreaRecord(routeData)
      routeData.wayline_folder.polygon.map((item) => {
        LonLat.push(Number(item.longitude))
        LonLat.push(Number(item.latitude))
      })
      const positions = Cesium.Cartesian3.fromDegreesArray(LonLat)
      const entity = showArea(objId, positions, areaLayerName)
      GodViewer.value.flyTo(entity)
    } else {
      // 如果没有区域数据，使用config.js中的initialPosition
      const initialPos = window.SystemConfig?.initialPosition?.destination
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(...initialPos),
      })
      draw3DPlane()
    }
  }

  /**
   * 初始化沿线模式
   */
  const initLineMode = async (routeData) => {
    
    const LonLat = []
    const objId = uuidv4()
    
    // 沿线巡检模式使用polyline数据作为线条路径
    if (routeData.wayline_folder.polyline && routeData.wayline_folder.polyline.length > 0) {
      routeData.wayline_folder.polyline.map((item) => {
        LonLat.push(Number(item.longitude))
        LonLat.push(Number(item.latitude))
      })
      const positions = Cesium.Cartesian3.fromDegreesArray(LonLat)
      areaRecord.value = positions
      
      // 显示线条路径
      await showLine(objId, positions, routeData.wayline_folder.buffer || 0)
      
      // 设置相机视角到线条的第一个点
      const pointLoc = routeData.wayline_folder.polyline[0]
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(Number(pointLoc.longitude), Number(pointLoc.latitude), 1200.0),
      })
    } else {
      // 如果没有线条数据，使用config.js中的initialPosition
      const initialPos = window.SystemConfig?.initialPosition?.destination
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(...initialPos),
      })
    }
  }

  /**
   * 初始化立体巡检模式
   */
  const initBuildingMode = async (routeData) => {
    
    const LonLat = []
    const objId = uuidv4()
    
    // 立体巡检模式使用polygon数据作为3D区域
    if (routeData.wayline_folder.polygon && routeData.wayline_folder.polygon.length > 0) {
      routeData.wayline_folder.polygon.map((item) => {
        LonLat.push(Number(item.longitude))
        LonLat.push(Number(item.latitude))
      })
      const positions = Cesium.Cartesian3.fromDegreesArray(LonLat)
      areaRecord.value = positions
      
      // 显示3D区域
      const entity = await showArea(objId, positions, areaLayerName)
      
      // 设置相机视角到区域的第一个点，高度更高以显示立体效果
      const pointLoc = routeData.wayline_folder.polygon[0]
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(Number(pointLoc.longitude), Number(pointLoc.latitude), 2000.0),
      })
      
      // 如果有实体，飞行到该实体
      if (entity) {
        GodViewer.value.flyTo(entity)
      }
    } else {
      // 如果没有区域数据，使用config.js中的initialPosition并绘制3D平面
      const initialPos = window.SystemConfig?.initialPosition?.destination
      GodViewer.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(...initialPos),
      })
      draw3DPlane()
    }
  }

  /**
   * 定位到指定位置
   */
  const locate = (position) => {
    GodViewer.value.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(Number(position[0]), Number(position[1]), 150.0)
    })
    
    if (hightLight.value !== null) {
      GodViewer.value.entities.remove(hightLight.value)
    }
    
    hightLight.value = GodViewer.value.entities.add({
      name: 'hightLight',
      layerId: 'hightLightLayer',
      position: Cesium.Cartesian3.fromDegrees(Number(position[0]), Number(position[1])),
      point: {
        pixelSize: 8,
        color: Cesium.Color.YELLOW,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 2
      }
    })
    
    let observer = Cesium.Cartesian3.fromDegrees(Number(position[0]), Number(position[1]), uav_height.value)
    let target = Cesium.Cartesian3.fromDegrees(Number(position[0]), Number(position[1]), target_height.value)
    let frustum = CameraFrustum.CreateFrustumByTarget(GodViewer.value, observer, target, 55, 1.33, null, null)

    frustumVisible.value = true
    showFrustum.value.UpdateFrustum(frustum)
  }

  /**
   * 设置目标点
   */
  const SetTarget = (observer, position) => {
    const cartographic = Cesium.Cartographic.fromCartesian(position)
    const longitude = Cesium.Math.toDegrees(cartographic.longitude)
    const latitude = Cesium.Math.toDegrees(cartographic.latitude)

    console.log(`拾取到的坐标：经度 ${longitude}, 纬度 ${latitude}, 高程 ${cartographic.height}`)

    let frustum = CameraFrustum.CreateFrustumByTarget(GodViewer.value, observer, position, 55, 1.33, null, 2)
    frustum.SetUavViewer(UavViewer.value, "UavMapPanel")
    showFrustum.value.UpdateFrustum(frustum)
  }

  /**
   * 切换显示
   */
  const SwitchDisplay = () => {
    frustumVisible.value = !frustumVisible.value
    showFrustum.value.SetVisible(frustumVisible.value)
  }

  /**
   * 清空地图实体
   */
  const clear = () => {
    console.log('清空地图实体')
  }

  // 辅助函数
  const processPointRecord = (routeData) => {
    const uavPositions = routeData?.wayline_folder?.uav_positions || []
    
    pointRecord.value = uavPositions.map((item, index) => {
      // 获取无人机位置
      const camera_lng = Number(item.point_coordinate.longitude)
      const camera_lat = Number(item.point_coordinate.latitude)
      const camera_ground_height = Number(item.point_fly_height) || 0
      
      // 计算目标点位置
      let target_lng = camera_lng
      let target_lat = camera_lat
      let target_ground_height = 0
      
      const pointActions = item.point_actions || []
      
      // 首先检查是否存在 action_type == 40，如果存在则直接使用其 point_ground 坐标
      let action40 = null
      for (let i = 0; i < pointActions.length; i++) {
        if (pointActions[i].action_type === 40) {
          action40 = pointActions[i]
          break
        }
      }
      
      if (action40 && action40.point_ground) {
        // 如果存在 action_type == 40，直接使用其 point_ground 坐标
        target_lng = Number(action40.point_ground.longitude)
        target_lat = Number(action40.point_ground.latitude)
        target_ground_height = Number(action40.point_ground.altitude) || 0
      } else {
        // 如果不存在 action_type == 40，则使用 action_type == 6 和 action_type == 7 的逻辑
        let headingAngle = null // 航向角
        let pitchAngle = null // 俯仰角
        
        for (let i = 0; i < pointActions.length; i++) {
          const action = pointActions[i]
          if (action.action_type === 6) {
            headingAngle = action.action_param_value
          } else if (action.action_type === 7) {
            pitchAngle = action.action_param_value
          }
        }
        
        // 如果没有找到 action_type == 6，默认使用航向方向（计算从上一个航点到当前航点的航向）
        if (headingAngle === null) {
          if (index > 0 && uavPositions.length > index - 1) {
            const prevItem = uavPositions[index - 1]
            if (prevItem && prevItem.point_coordinate) {
              const prevPoint = Cesium.Cartesian3.fromDegrees(
                Number(prevItem.point_coordinate.longitude),
                Number(prevItem.point_coordinate.latitude)
              )
              const currentPoint = Cesium.Cartesian3.fromDegrees(camera_lng, camera_lat)
              headingAngle = Tools.HeadingPointToPoint(prevPoint, currentPoint)
            } else {
              headingAngle = 0
            }
          } else {
            headingAngle = 0
          }
        }
        
        // 如果没有找到 action_type == 7，默认垂直向下90°
        if (pitchAngle === null) {
          pitchAngle = -90
        }
        
        // 根据航向角和俯仰角计算目标点
        const observer = Cesium.Cartesian3.fromDegrees(
          camera_lng,
          camera_lat,
          camera_ground_height
        )
        
        const viewDegree = new ViewDegree(headingAngle, pitchAngle)
        
        // 计算距离，使目标点在地面上
        const observerHeight = camera_ground_height
        let distance
        
        if (Math.abs(pitchAngle + 90) < 0.01) {
          // 垂直向下，距离就是高度
          distance = observerHeight
        } else {
          // 根据俯仰角计算距离，使目标点在地面上
          const pitchRad = Cesium.Math.toRadians(Math.abs(pitchAngle))
          distance = observerHeight / Math.sin(pitchRad)
        }
        
        // 使用 Tools.GetPositionAlongViewDegree 计算目标点
        const target = Tools.GetPositionAlongViewDegree(observer, viewDegree, distance)
        
        // 确保目标点在地面上（高度为0或从地形获取）
        const targetCartographic = Cesium.Cartographic.fromCartesian(target)
        targetCartographic.height = 0 // 设置为地面高度
        const finalTarget = Cesium.Cartesian3.fromRadians(
          targetCartographic.longitude,
          targetCartographic.latitude,
          targetCartographic.height
        )
        
        const targetCartographicFinal = Cesium.Cartographic.fromCartesian(finalTarget)
        target_lng = Cesium.Math.toDegrees(targetCartographicFinal.longitude)
        target_lat = Cesium.Math.toDegrees(targetCartographicFinal.latitude)
        target_ground_height = 0
      }
      
      // 返回航线绘制所需的数据格式
      return {
        camera_lng: camera_lng,
        camera_lat: camera_lat,
        camera_ground_height: camera_ground_height,
        target_lng: target_lng,
        target_lat: target_lat,
        target_ground_height: target_ground_height,
        sky_index: index,
        target_index: index,
        fieldOfView: 55, // 默认视野角度
        aspect: 1.33 // 默认宽高比
      }
    })
  }

  const processAreaRecord = (routeData) => {
    console.log('处理区域记录', routeData)
  }

  const process3DAreaRecord = (routeData) => {
    console.log('处理3D区域记录', routeData)
  }

  const showArea = async (objId, positions, layerId) => {
    if (!GodViewer.value) {
      console.error('GodViewer 未定义，无法显示区域')
      return null
    }
    
    const material = new Cesium.ColorMaterialProperty(
      Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5)
    )
    const outlineMaterial = new Cesium.PolylineDashMaterialProperty({
      dashLength: 16,
      color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
    })
    
    const outlinePositions = [].concat(positions)
    outlinePositions.push(positions[0])
    
    const entity = GodViewer.value.entities.add({
      layerId: layerId || 'areaLayer',
      objId: objId,
      shapeType: "Polygon",
      polyline: {
        positions: outlinePositions,
        clampToGround: true,
        width: 2,
        material: outlineMaterial,
        height: 0,
      },
      polygon: new Cesium.PolygonGraphics({
        hierarchy: positions,
        asynchronous: false,
        material: material,
        height: 0,
      })
    })
    
    return entity
  }

  const draw3DPlane = () => {
    console.log('绘制3D平面')
  }

  /**
   * 显示线条路径
   */
  const showLine = async (lineId, positions, buffer) => {
    if (!GodViewer.value) {
      console.error('GodViewer 未定义，无法显示线条')
      return null
    }
    
    // 1. 绘制点
    positions.forEach((position, index) => {
      GodViewer.value.entities.add({
        layerId: areaLayerName,
        objId: lineId,
        shapeType: "Point",
        position: position,
        billboard: {
          image: "images/circle_red.png",
          eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
        },
        label: {
          text: `${index + 1}`,
          font: '15pt Helvetica',
          fillColor: Cesium.Color.WHITE,
          outlineColor: Cesium.Color.DARKBLUE,
          outlineWidth: 2,
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          verticalOrigin: Cesium.VerticalOrigin.TOP,
          pixelOffset: new Cesium.Cartesian2(-10, 10)
        }
      })
    })

    // 2. 绘制点连成的线
    const lineEntity = GodViewer.value.entities.add({
      layerId: areaLayerName,
      objId: lineId,
      shapeType: "Polyline",
      polyline: {
        positions: positions,
        clampToGround: true,
        width: 3,
        material: new Cesium.PolylineDashMaterialProperty({
          dashLength: 16,
          color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.8)
        })
      }
    })

    // 3. 以buffer为缓冲区半径绘制polygon面
    if (buffer && buffer > 0) {
      // 创建缓冲区多边形
      const bufferPositions = createBufferPolygon(positions, buffer)
      
      GodViewer.value.entities.add({
        layerId: areaLayerName,
        objId: lineId,
        shapeType: "Polygon",
        polygon: {
          hierarchy: bufferPositions,
          asynchronous: false,
          material: new Cesium.ColorMaterialProperty(
            Cesium.Color.fromCssColorString('#ff0').withAlpha(0.3)
          ),
          outline: true,
          outlineColor: Cesium.Color.fromCssColorString('#ff0').withAlpha(0.8)
        }
      })
    }

    return lineEntity
  }

  // 创建实例对象
  mapCoreInstance = {
    // 核心地图数据
    GodViewer,
    UavViewer,
    tracker,
    
    // 其他地图数据
    MapProvider2D,
    MapProvider3D,
    uav_height,
    target_height,
    frustumVisible,
    showFrustum,
    drawWayLine,
    hightLight,
    pointRecord,
    areaRecord,
    
    // 方法
    initMap,
    handleMapMode,
    initPointMode,
    initAreaMode,
    init3DAreaMode,
    initLineMode,
    initBuildingMode,
    locate,
    SetTarget,
    SwitchDisplay,
    clear,
    processPointRecord,
    processAreaRecord,
    process3DAreaRecord,
    showArea,
    showLine,
    draw3DPlane
  }

  return mapCoreInstance
}
